package com.wusongti.performance.service.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.wusongti.performance.dao.IPerformanceLogDao;
import com.wusongti.performance.model.entity.PerformanceLogEntity;
import com.wusongti.performance.model.params.PerformanceLogSearchParameter;
import com.wusongti.performance.model.vo.PerformanceLogVO;
import com.wusongti.performance.service.IPerformanceLogService;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;

/**
 * @ClassName: PerformanceLogServiceImpl
 * @author: wust
 * @date: 2022/04/28 17:06
 * @Description:
 */
@Service
public class PerformanceLogServiceImpl implements IPerformanceLogService {
    @Autowired
    private IPerformanceLogDao performanceLogDao;

    @Autowired
    private Environment env;

    /**
     * @ClassName: PerformanceLogServiceImpl
     * @author: wust
     * @date: 2022/04/28 17:06
     * @Description:
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int batchSave() {
        final List<PerformanceLogEntity> listAll = new ArrayList<PerformanceLogEntity>();

        final String logDir = env.getProperty("sysprop.log-dir");

        final List<String> fileNames = FileUtil.listFileNames(logDir);

        if (fileNames == null || fileNames.size() == 0) {
            return 0;
        }

        for (String fileName : fileNames) {

            final ArrayList<PerformanceLogEntity> list = parseLog(logDir + fileName);

            if (list != null) {
                listAll.addAll(list);
            }

        }

        return performanceLogDao.batchSave(listAll);
    }

    /**
     * @ClassName: PerformanceLogServiceImpl
     * @author: wust
     * @date: 2022/04/28 17:06
     * @Description:
     */
    @Override
    public List<PerformanceLogVO> findAll(final PerformanceLogSearchParameter parameter) {
        return performanceLogDao.findAll(parameter);
    }

    /**
     * @ClassName: 删除数据库日志
     * @author: wust
     * @date: 2022/04/28 17:07
     * @Description:
     */
    @Override
    public int deleteAll() {
        return performanceLogDao.deleteAll();
    }

    /**
     * @ClassName: PerformanceLogServiceImpl
     * @author: wust
     * @date: 2022/04/28 17:06
     * @Description: 解析日志
     */
    private ArrayList<PerformanceLogEntity> parseLog(final String filePath) {
        final ArrayList<PerformanceLogEntity> list = new ArrayList<PerformanceLogEntity>();

        try {
            final File file = new File(filePath);

            FileInputStream fis = new FileInputStream(file);

            InputStreamReader isr = new InputStreamReader(fis, "UTF-8");

            final BufferedReader br = new BufferedReader(isr);

            int seq = 0;

            String s = null;

            while ((s = br.readLine()) != null) {
                if (s == null || s.trim().isEmpty()) {
                    continue;
                }

                if (!s.contains("@@")) {
                    continue;
                }

                final String[] strs = s.split("@@");

                if (strs.length != 5) {
                    continue;
                }

                final PerformanceLogEntity model = new PerformanceLogEntity();

                try {
                    model.setTypeName(file.getName());

                    model.setSeq(seq++);

                    model.setMethodName(strs[0]);

                    if (!StrUtil.isEmptyIfStr(strs[1]) && NumberUtil.isNumber(strs[1])) {
                        model.setLineNo(Integer.parseInt(strs[1]));
                    }

                    if (!StrUtil.isEmptyIfStr(strs[2]) && NumberUtil.isNumber(strs[2])) {
                        model.setTotalTime(Integer.parseInt(strs[2]));
                    }

                    model.setThreadId(Integer.parseInt(strs[3]));

                    model.setTimeMillis(Long.parseLong(strs[4]));

                    model.setCreateDate(new Date());

                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }

                list.add(model);

            }

            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return list;
    }
}
